home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 2
/
AACD 2.iso
/
AACD
/
Magazine
/
GraphicsCards
/
StormMesa
/
demos
/
tessdemo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-12-15
|
10KB
|
460 lines
/* $Id: tessdemo.c,v 3.3 1998/07/26 01:25:26 brianp Exp $ */
/*
* A demo of the GLU polygon tesselation functions written by Bogdan Sikorski.
* This demo isn't built by the Makefile because it needs GLUT. After you've
* installed GLUT you can try this demo.
* Here's the command for IRIX, for example:
cc -g -ansi -prototypes -fullwarn -float -I../include -DSHM tess_demo.c -L../lib -lglut -lMesaGLU -lMesaGL -lm -lX11 -lXext -lXmu -lfpe -lXext -o tess_demo
*/
/*
* $Log: tessdemo.c,v $
* Revision 3.3 1998/07/26 01:25:26 brianp
* removed include of gl.h and glu.h
*
* Revision 3.2 1998/06/29 02:37:30 brianp
* minor changes for Windows (Ted Jump)
*
* Revision 3.1 1998/06/09 01:53:49 brianp
* main() should return an int
*
* Revision 3.0 1998/02/14 18:42:29 brianp
* initial rev
*
*/
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_POINTS 200
#define MAX_CONTOURS 50
int menu;
typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries;
typedef enum{ DEFINE, TESSELATED } mode_type;
struct
{
GLint p[MAX_POINTS][2];
GLuint point_cnt;
} contours[MAX_CONTOURS];
GLuint contour_cnt;
GLsizei width,height;
mode_type mode;
struct
{
GLsizei no;
GLfloat color[3];
GLint p[3][2];
GLclampf p_color[3][3];
} triangle;
void CALLBACK my_error(GLenum err)
{
int len,i;
#ifndef __STORM__
char const *str;
#else
const char *str;
#endif
glColor3f(0.9,0.9,0.9);
glRasterPos2i(5,5);
str=(const char *)gluErrorString(err);
len=strlen(str);
for(i=0;i<len;i++)
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,str[i]);
}
void CALLBACK begin_callback(GLenum mode)
{
triangle.no=0;
}
void CALLBACK edge_callback(GLenum flag)
{
if(flag==GL_TRUE)
{
triangle.color[0]=1.0;
triangle.color[1]=1.0;
triangle.color[2]=0.5;
}
else
{
triangle.color[0]=1.0;
triangle.color[1]=0.0;
triangle.color[2]=0.0;
}
}
void CALLBACK end_callback()
{
glBegin(GL_LINES);
glColor3f(triangle.p_color[0][0],triangle.p_color[0][1],
triangle.p_color[0][2]);
glVertex2i(triangle.p[0][0],triangle.p[0][1]);
glVertex2i(triangle.p[1][0],triangle.p[1][1]);
glColor3f(triangle.p_color[1][0],triangle.p_color[1][1],
triangle.p_color[1][2]);
glVertex2i(triangle.p[1][0],triangle.p[1][1]);
glVertex2i(triangle.p[2][0],triangle.p[2][1]);
glColor3f(triangle.p_color[2][0],triangle.p_color[2][1],
triangle.p_color[2][2]);
glVertex2i(triangle.p[2][0],triangle.p[2][1]);
glVertex2i(triangle.p[0][0],triangle.p[0][1]);
glEnd();
}
void CALLBACK vertex_callback(void *data)
{
GLsizei no;
GLint *p;
p=(GLint *)data;
no=triangle.no;
triangle.p[no][0]=p[0];
triangle.p[no][1]=p[1];
triangle.p_color[no][0]=triangle.color[0];
triangle.p_color[no][1]=triangle.color[1];
triangle.p_color[no][2]=triangle.color[2];
++(triangle.no);
}
void set_screen_wh(GLsizei w, GLsizei h)
{
width=w;
height=h;
}
#if defined(AMIGA) && defined(__PPC__)
void CALLBACK my_glBegin(GLenum a)
{
glBegin(a);
}
void CALLBACK my_glEnd()
{
glEnd();
}
void CALLBACK my_glVertex2iv(void* a)
{
glVertex2iv(a);
}
#endif
void tesse(void)
{
GLUtriangulatorObj *tobj;
GLdouble data[3];
GLuint i,j,point_cnt;
tobj=gluNewTess();
if(tobj!=NULL)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (0.7, 0.7, 0.0);
#if defined(AMIGA) && defined(__PPC__)
gluTessCallback(tobj,GLU_BEGIN,(void(CALLBACK *)())my_glBegin);
gluTessCallback(tobj,GLU_END,(void(CALLBACK *)())my_glEnd);
gluTessCallback(tobj,GLU_ERROR,(void(CALLBACK *)())my_error);
gluTessCallback(tobj,GLU_VERTEX,(void(CALLBACK *)())my_glVertex2iv);
#else
#ifndef __STORM__
gluTessCallback(tobj,GLU_BEGIN,glBegin);
gluTessCallback(tobj,GLU_END,glEnd);
gluTessCallback(tobj,GLU_ERROR,my_error);
gluTessCallback(tobj,GLU_VERTEX,glVertex2iv);
#else
gluTessCallback(tobj,GLU_BEGIN,(void(CALLBACK *)())glBegin);
gluTessCallback(tobj,GLU_END,(void(CALLBACK *)())glEnd);
gluTessCallback(tobj,GLU_ERROR,(void(CALLBACK *)())my_error);
gluTessCallback(tobj,GLU_VERTEX,(void(CALLBACK *)())glVertex2iv);
#endif
#endif
gluBeginPolygon(tobj);
for(j=0;j<=contour_cnt;j++)
{
point_cnt=contours[j].point_cnt;
gluNextContour(tobj,GLU_UNKNOWN);
for(i=0;i<point_cnt;i++)
{
data[0]=(GLdouble)(contours[j].p[i][0]);
data[1]=(GLdouble)(contours[j].p[i][1]);
data[2]=0.0;
gluTessVertex(tobj,data,contours[j].p[i]);
}
}
gluEndPolygon(tobj);
glLineWidth(2.0);
#ifndef __STORM__
gluTessCallback(tobj,GLU_BEGIN,begin_callback);
gluTessCallback(tobj,GLU_END,end_callback);
gluTessCallback(tobj,GLU_VERTEX,vertex_callback);
gluTessCallback(tobj,GLU_EDGE_FLAG,edge_callback);
#else
gluTessCallback(tobj,GLU_BEGIN,(void(CALLBACK *)())begin_callback);
gluTessCallback(tobj,GLU_END,(void(CALLBACK *)())end_callback);
gluTessCallback(tobj,GLU_VERTEX,(void(CALLBACK *)())vertex_callback);
gluTessCallback(tobj,GLU_EDGE_FLAG,(void(CALLBACK *)())edge_callback);
#endif
gluBeginPolygon(tobj);
for(j=0;j<=contour_cnt;j++)
{
point_cnt=contours[j].point_cnt;
gluNextContour(tobj,GLU_UNKNOWN);
for(i=0;i<point_cnt;i++)
{
data[0]=(GLdouble)(contours[j].p[i][0]);
data[1]=(GLdouble)(contours[j].p[i][1]);
data[2]=0.0;
gluTessVertex(tobj,data,contours[j].p[i]);
}
}
gluEndPolygon(tobj);
gluDeleteTess(tobj);
glutMouseFunc(NULL);
glColor3f (1.0, 1.0, 0.0);
glLineWidth(1.0);
mode=TESSELATED;
}
}
void left_down(int x1,int y1)
{
GLint P[2];
GLuint point_cnt;
/* translate GLUT into GL coordinates */
P[0]=x1;
P[1]=height-y1;
point_cnt=contours[contour_cnt].point_cnt;
contours[contour_cnt].p[point_cnt][0]=P[0];
contours[contour_cnt].p[point_cnt][1]=P[1];
glBegin(GL_LINES);
if(point_cnt)
{
glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
glVertex2iv(P);
}
else
{
glVertex2iv(P);
glVertex2iv(P);
}
glEnd();
glFinish();
++(contours[contour_cnt].point_cnt);
}
void middle_down(int x1,int y1)
{
GLuint point_cnt;
point_cnt=contours[contour_cnt].point_cnt;
if(point_cnt>2)
{
glBegin(GL_LINES);
glVertex2iv(contours[contour_cnt].p[0]);
glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
contours[contour_cnt].p[point_cnt][0]= -1;
glEnd();
glFinish();
contour_cnt++;
contours[contour_cnt].point_cnt=0;
}
}
void mouse_clicked(int button,int state,int x,int y)
{
x-= x%10;
y-= y%10;
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state==GLUT_DOWN)
left_down(x,y);
break;
case GLUT_MIDDLE_BUTTON:
if(state==GLUT_DOWN)
middle_down(x,y);
break;
}
}
void display(void)
{
GLuint i,j;
GLuint point_cnt;
glClear(GL_COLOR_BUFFER_BIT);
switch(mode)
{
case DEFINE:
/* draw grid */
glColor3f (0.6,0.5,0.5);
glBegin(GL_LINES);
for(i=0;i<width;i+=10)
for(j=0;j<height;j+=10)
{
glVertex2i(0,j);
glVertex2i(width,j);
glVertex2i(i,height);
glVertex2i(i,0);
}
glColor3f (1.0, 1.0, 0.0);
for(i=0;i<=contour_cnt;i++)
{
point_cnt=contours[i].point_cnt;
glBegin(GL_LINES);
switch(point_cnt)
{
case 0:
break;
case 1:
glVertex2iv(contours[i].p[0]);
glVertex2iv(contours[i].p[0]);
break;
case 2:
glVertex2iv(contours[i].p[0]);
glVertex2iv(contours[i].p[1]);
break;
default:
--point_cnt;
for(j=0;j<point_cnt;j++)
{
glVertex2iv(contours[i].p[j]);
glVertex2iv(contours[i].p[j+1]);
}
if(contours[i].p[j+1][0]== -1)
{
glVertex2iv(contours[i].p[0]);
glVertex2iv(contours[i].p[j]);
}
break;
}
glEnd();
}
glFinish();
break;
case TESSELATED:
/* draw lines */
tesse();
break;
}
glColor3f (1.0, 1.0, 0.0);
}
void clear( void )
{
contour_cnt=0;
contours[0].point_cnt=0;
glutMouseFunc(mouse_clicked);
mode=DEFINE;
display();
}
void quit( void )
{
exit(0);
}
void menu_selected(int entry)
{
switch(entry)
{
case CLEAR:
clear();
break;
case TESSELATE:
tesse();
break;
case QUIT:
quit();
break;
}
}
void key_pressed(unsigned char key,int x,int y)
{
switch(key)
{
case 't':
case 'T':
tesse();
glFinish();
break;
case 'q':
case 'Q':
quit();
break;
case 'c':
case 'C':
clear();
break;
}
}
void myinit (void)
{
/* clear background to gray */
glClearColor (0.4, 0.4, 0.4, 0.0);
glShadeModel (GL_FLAT);
menu=glutCreateMenu(menu_selected);
glutAddMenuEntry("clear",CLEAR);
glutAddMenuEntry("tesselate",TESSELATE);
glutAddMenuEntry("quit",QUIT);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMouseFunc(mouse_clicked);
glutKeyboardFunc(key_pressed);
contour_cnt=0;
glPolygonMode(GL_FRONT,GL_FILL);
mode=DEFINE;
}
static void reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
set_screen_wh(w,h);
}
static void usage( void )
{
printf("Use left mouse button to place vertices.\n");
printf("Press middle mouse button when done.\n");
printf("Select tesselate from the pop-up menu.\n");
}
/* Main Loop
* Open window with initial window size, title bar,
* RGBA display mode, and handle input events.
*/
int main(int argc, char** argv)
{
usage();
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (400, 400);
glutCreateWindow (argv[0]);
myinit ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}